Skip to content

Conversation

@shwstppr
Copy link
Contributor

@shwstppr shwstppr commented Oct 1, 2025

Description

Fixes #10823

Types of changes

  • Breaking change (fix or feature that would cause existing functionality to change)
  • New feature (non-breaking change which adds functionality)
  • Bug fix (non-breaking change which fixes an issue)
  • Enhancement (improves an existing feature and functionality)
  • Cleanup (Code refactoring and cleanup, that may add test cases)
  • Build/CI
  • Test (unit or integration test code)

Feature/Enhancement Scale or Bug Severity

Feature/Enhancement Scale

  • Major
  • Minor

Bug Severity

  • BLOCKER
  • Critical
  • Major
  • Minor
  • Trivial

Screenshots (if appropriate):

How Has This Been Tested?

How did you try to break this feature and the system with this change?

@codecov
Copy link

codecov bot commented Oct 1, 2025

Codecov Report

❌ Patch coverage is 86.66667% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 17.50%. Comparing base (d60f455) to head (4b28714).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
.../cloud/configuration/ConfigurationManagerImpl.java 80.00% 1 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff            @@
##               main   #11770   +/-   ##
=========================================
  Coverage     17.50%   17.50%           
- Complexity    15427    15434    +7     
=========================================
  Files          5894     5894           
  Lines        526847   526855    +8     
  Branches      64335    64337    +2     
=========================================
+ Hits          92234    92251   +17     
+ Misses       424236   424227    -9     
  Partials      10377    10377           
Flag Coverage Δ
uitests 3.61% <ø> (ø)
unittests 18.56% <86.66%> (+<0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Signed-off-by: Abhishek Kumar <[email protected]>
@shwstppr
Copy link
Contributor Author

shwstppr commented Oct 1, 2025

@blueorangutan package

@blueorangutan
Copy link

@shwstppr a [SL] Jenkins job has been kicked to build packages. It will be bundled with KVM, XenServer and VMware SystemVM templates. I'll keep you posted as I make progress.

@blueorangutan
Copy link

Packaging result [SF]: ✔️ el8 ✔️ el9 ✔️ el10 ✔️ debian ✔️ suse15. SL-JID 15253

Copy link
Contributor

@DaanHoogland DaanHoogland left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

clgtm

return "";
}
ConfigKey<?> key = _configDepot.get(name);
return (key != null && key.type() == String.class) ? "" : null;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

edge case: can the default value of a String be NULL?
we have the key here so we could as well check the default value for that. However, when “” is passed is it meant to be a reset or an explicit set to “”…?
I think this is the best we can do now, except maybe for making the value field non-null completely.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@DaanHoogland I feel we should let updateConfiguration set empty string ""
If the operator wants NULL(if NULL is default value), resetConfiguration API can be used.

@shwstppr
Copy link
Contributor Author

shwstppr commented Nov 3, 2025

@blueorangutan package

@blueorangutan
Copy link

@shwstppr a [SL] Jenkins job has been kicked to build packages. It will be bundled with KVM, XenServer and VMware SystemVM templates. I'll keep you posted as I make progress.

@blueorangutan
Copy link

Packaging result [SF]: ✔️ el8 ✔️ el9 ✔️ el10 ✔️ debian ✔️ suse15. SL-JID 15615

@shwstppr shwstppr marked this pull request as ready for review November 3, 2025 10:42
@vishesh92 vishesh92 requested a review from Copilot November 4, 2025 10:34
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR refactors configuration value handling by extracting normalization logic into a dedicated method and fixes a bug in the UpdateCfgCmd.setResponseValue method. The key changes include:

  • Extracted empty/null value normalization logic into a reusable getNormalizedEmptyValueForConfig method
  • Fixed the setResponseValue method to use the configuration's value instead of the command's value
  • Added comprehensive test coverage for the new normalization method

Reviewed Changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.

File Description
ConfigurationManagerImpl.java Extracts value normalization logic into a new protected method and refactors updateConfiguration to use it
ConfigurationManagerImplTest.java Adds 5 test cases covering various scenarios for the new getNormalizedEmptyValueForConfig method
UpdateCfgCmd.java Changes setResponseValue to return void and fixes bug where command value was used instead of configuration value
UpdateCfgCmdTest.java Adds new test file with 3 test cases for the setResponseValue method

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

public void normalizedEmptyValueForConfigReturnsEmptyStringWhenKeyTypeIsStringAndInputIsEmpty() {
ConfigKey<String> mockKey = Mockito.mock(ConfigKey.class);
Mockito.when(mockKey.type()).thenReturn(String.class);
Mockito.doReturn(mockKey).when(configDepot).get("someConfig");
Copy link

Copilot AI Nov 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The mock is being set on configDepot directly, but the production code uses _configDepot (with underscore prefix). This test will fail because the spy instance configurationManagerImplSpy uses the _configDepot field which is injected via @InjectMocks. The mock should be set on configurationManagerImplSpy._configDepot instead, like other tests in this file (see lines 379, 387, 394, etc.).

Copilot uses AI. Check for mistakes.
public void normalizedEmptyValueForConfigReturnsNullWhenKeyTypeIsNotStringAndInputIsEmpty() {
ConfigKey<Integer> mockKey = Mockito.mock(ConfigKey.class);
Mockito.when(mockKey.type()).thenReturn(Integer.class);
Mockito.doReturn(mockKey).when(configDepot).get("someConfig");
Copy link

Copilot AI Nov 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The mock is being set on configDepot directly, but the production code uses _configDepot (with underscore prefix). This test will fail because the spy instance configurationManagerImplSpy uses the _configDepot field which is injected via @InjectMocks. The mock should be set on configurationManagerImplSpy._configDepot instead, like other tests in this file (see lines 379, 387, 394, etc.).

Copilot uses AI. Check for mistakes.

protected String getNormalizedEmptyValueForConfig(final String name, final String inputValue,
final Long configStorageId) {
String value = inputValue.trim();
Copy link

Copilot AI Nov 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing null check for inputValue. If inputValue is null, calling trim() will throw a NullPointerException. Based on the method signature and test cases, the method should handle null inputs gracefully.

Suggested change
String value = inputValue.trim();
String value = StringUtils.defaultString(inputValue).trim();

Copilot uses AI. Check for mistakes.
public ConfigurationResponse setResponseValue(ConfigurationResponse response, Configuration cfg) {
public void setResponseValue(ConfigurationResponse response, Configuration cfg) {
String value = cfg.getValue();
if (cfg.isEncrypted()) {
Copy link

Copilot AI Nov 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing null check for cfg.getValue(). If cfg.getValue() returns null and cfg.isEncrypted() is true, DBEncryptionUtil.encrypt(null) will be called which may cause issues. Consider checking if value is null before encryption, as shown in the test case on line 76.

Suggested change
if (cfg.isEncrypted()) {
if (cfg.isEncrypted() && value != null) {

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Normalize empty values for global settings

3 participants